package com.jsb.laundry.common.utils.http;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.net.ssl.HttpsURLConnection;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 封装HTTP请求
 *
 */
public class HttpUtil {

    private static final Logger LOGGER = LoggerFactory.getLogger(HttpUtil.class);


    /**
     * 发送 GET 请求(HTTP)
     * @param url     请求地址
     * @param headers 请求头
     * @param params  请求参数
     * @param responseStreamCharsetName 设置响应数据流字符编码 默认UTF-8
     * @return
     */
    public static String sendGet(String url, Map<String, String> headers, Map<String, Object> params, String responseStreamCharsetName) {
        //请求参数拼接
        String apiUrl = url;
        StringBuffer param = new StringBuffer();
        // 构建请求参数
        if (params != null) {
            int i = 0;
            for (String key : params.keySet()) {
                if (i == 0)
                    param.append("?");
                else
                    param.append("&");
                param.append(key).append("=").append(params.get(key));
                i++;
            }
            apiUrl += param;
        }

        //请求构建
        StringBuilder result = new StringBuilder();
        HttpURLConnection conn = null;
        BufferedReader in = null;
        try {
            URL realUrl = new URL(apiUrl);
            // 打开和URL之间的连接
            conn = (HttpURLConnection) realUrl.openConnection();
            // 设置通用的请求属性
            conn.setRequestMethod("GET");
            conn.setRequestProperty("accept", "*/*");
            conn.setRequestProperty("connection", "Keep-Alive");
            conn.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
            conn.setRequestProperty("Accept-Charset", "utf-8");
            conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded;charset=utf-8");
            conn.setUseCaches(false);
            // 设置连接超时时间为5秒
            conn.setConnectTimeout(5000);
            conn.setReadTimeout(5000);

            // 携带的请求头
            if (headers != null) {
                headers.forEach(conn::setRequestProperty);
            }
            //设置响应数据流字符编码 默认UTF-8
            if (responseStreamCharsetName == null) {
                responseStreamCharsetName = "UTF-8";
            }

            // 建立实际的连接
            conn.connect();
            // 定义 BufferedReader输入流来读取URL的响应
            in = new BufferedReader(new InputStreamReader(conn.getInputStream(), responseStreamCharsetName));
            String line;
            while ((line = in.readLine()) != null) {
                result.append(line);
            }
        } catch (IOException e) {
            LOGGER.error("调用HttpUtil.sendGet Exception, url=" + apiUrl + ",param=" + params, e);
        } finally {
            try {
                if (in != null) {
                    in.close();
                }
                if (conn != null) {
                    conn.disconnect();
                }
            } catch (IOException ex) {
            }
        }
        return String.valueOf(result);
    }

    /**
     * 发送 GET 请求(HTTPS)
     *
     * @param url     请求地址
     * @param headers 请求头
     * @param params  请求参数
     * @return
     */
    public static String sendHttpsGet(String url, Map<String, String> headers, Map<String, Object> params) {
        StringBuilder apiUrl = new StringBuilder(url);
        StringBuilder param = new StringBuilder();
        // 构建请求参数
        if (params != null) {
            int i = 0;
            for (String key : params.keySet()) {
                try {
                    param.append(i == 0 ? "?" : "&")
                            .append(URLEncoder.encode(key, "UTF-8"))
                            .append("=")
                            .append(URLEncoder.encode(params.get(key).toString(), "UTF-8"));
                } catch (UnsupportedEncodingException e) {
                    throw new RuntimeException(e);
                }
                i++;
            }
            apiUrl.append(param);
        }

        String result = null;
        HttpsURLConnection conn = null;
        BufferedReader reader = null;
        try {
            URL realUrl = new URL(apiUrl.toString());
            conn = (HttpsURLConnection) realUrl.openConnection();
            conn.setRequestMethod("GET");
            conn.setRequestProperty("accept", "*/*");
            conn.setRequestProperty("connection", "Keep-Alive");
            conn.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
            conn.setRequestProperty("Accept-Charset", "utf-8");
            conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded;charset=utf-8");
            conn.setUseCaches(false);
            // 设置连接超时时间为5秒
            conn.setConnectTimeout(5000);
            conn.setReadTimeout(5000);
            if (headers != null) {
                headers.forEach(conn::setRequestProperty);
            }
            conn.connect();

            reader = new BufferedReader(new InputStreamReader(conn.getInputStream(), StandardCharsets.UTF_8));
            result = reader.lines().collect(Collectors.joining());
        } catch (IOException e) {
            LOGGER.error("调用HttpUtil.sendHttpsGet Exception, url=" + apiUrl + ",param=" + params, e);
        } finally {
            try {
                if (reader != null) {
                    reader.close();
                }
                if (conn != null) {
                    conn.disconnect();
                }
            } catch (IOException ex) {
            }
        }
        return result;
    }

    /**
     * 发送 POST 请求（HTTP）
     *
     * @param url     请求地址
     * @param headers 请求头
     * @param params  请求参数 json字符串
     * @return
     */
    public static String sendPost(String url, Map<String, String> headers, String params) {
        HttpURLConnection conn = null;
        BufferedReader reader = null;
        StringBuilder result = new StringBuilder();
        try {
            URL realUrl = new URL(url);
            conn = (HttpURLConnection) realUrl.openConnection();
            // 设置通用的请求属性
            conn.setRequestMethod("POST");
            conn.setRequestProperty("accept", "*/*");
            conn.setRequestProperty("connection", "Keep-Alive");
            conn.setRequestProperty("user-agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64)");
            conn.setRequestProperty("Accept-Charset", "utf-8");
            conn.setRequestProperty("Content-Type", "application/json");
            conn.setUseCaches(false);
            // 设置连接超时时间为5秒
            conn.setConnectTimeout(5000);
            conn.setReadTimeout(5000);
            // 可以向服务器发送数据、读取服务器响应数据
            conn.setDoOutput(true);
            conn.setDoInput(true);

            //设置请求头
            if (headers != null) {
                headers.forEach(conn::setRequestProperty);
            }

            DataOutputStream out = new DataOutputStream(conn.getOutputStream());
            out.writeBytes(params);
            out.flush();
            out.close();

            reader = new BufferedReader(new InputStreamReader(conn.getInputStream(), StandardCharsets.UTF_8));
            String line;
            while ((line = reader.readLine()) != null) {
                result.append(line);
            }
        } catch (IOException e) {
            LOGGER.error("调用HttpUtil.sendPost Exception, url={},param={},e={}", url, params, e);
        } finally {
            try {
                if (reader != null) {
                    reader.close();
                }
                if (conn != null) {
                    conn.disconnect();
                }
            } catch (IOException ex) {
            }
        }
        return String.valueOf(result);
    }

    /**
     * 发送 POST 请求（HTTPS）
     *
     * @param url     请求地址
     * @param headers 请求头
     * @param params  请求参数 json字符串
     * @return
     */
    public static String sendHttpsPost(String url, Map<String, String> headers, String params) {
        PrintWriter out = null;
        BufferedReader in = null;
        StringBuilder result = new StringBuilder();
        HttpsURLConnection conn = null;
        try {
            URL realUrl = new URL(url);
            conn = (HttpsURLConnection) realUrl.openConnection();
            conn.setRequestMethod("POST");
            conn.setRequestProperty("accept", "*/*");
            conn.setRequestProperty("connection", "Keep-Alive");
            conn.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
            conn.setRequestProperty("Accept-Charset", "utf-8");
            conn.setRequestProperty("Content-Type", "application/json");
            conn.setUseCaches(false);
            // 设置连接超时时间为5秒
            conn.setConnectTimeout(5000);
            conn.setReadTimeout(5000);
            // 可以向服务器发送数据、读取服务器响应数据
            conn.setDoOutput(true);
            conn.setDoInput(true);
            // 设置请求头
            if (headers != null) {
                headers.forEach(conn::setRequestProperty);
            }

            out = new PrintWriter(conn.getOutputStream());
            // 发送请求参数
            out.print(params);
            out.flush();

            in = new BufferedReader(new InputStreamReader(conn.getInputStream(), StandardCharsets.UTF_8));
            String line;
            while ((line = in.readLine()) != null) {
                result.append(line);
            }
        } catch (Exception e) {
            LOGGER.error("调用HttpUtil.sendHttpsPost Exception, url={},param={},e={}", url, params, e);
        } finally {
            try {
                if (out != null) {
                    out.close();
                }
                if (in != null) {
                    in.close();
                }
                if (conn != null) {
                    conn.disconnect();
                }
            } catch (IOException ex) {
            }
        }
        return String.valueOf(result);
    }

}

